/**
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!
// This file should be overwritten as part of your build process.
// If you need to extend the behavior of the generated service worker, the best approach is to write
// additional code and include it using the importScripts option:
//   https://github.com/GoogleChrome/sw-precache#importscripts-arraystring
//
// Alternatively, it's possible to make changes to the underlying template file and then use that as the
// new base for generating output, via the templateFilePath option:
//   https://github.com/GoogleChrome/sw-precache#templatefilepath-string
//
// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any
// changes made to this original template file with your modified copy.

// This generated service worker JavaScript will precache your site's resources.
// The code needs to be saved in a .js file at the top-level of your site, and registered
// from your pages in order to be used. See
// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js
// for an example of how you can register this script and handle various service worker events.

/* eslint-env worker, serviceworker */
/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */
'use strict';

var precacheConfig = [["/2020/07/04/MySQL笔记-1-终端基本操作/index.html","3330983c473d9b0bb134f9c41bceab72"],["/2020/07/04/MySQL笔记-2-查询练习/index.html","07033ec2182c97f961d33674333dadcb"],["/2020/07/04/MySQL笔记-3-连接查询/index.html","5a1f8f23cf6a6d5c30ee6d7ea714a5d6"],["/2020/07/04/MySQL笔记-4-事务/index.html","f5ce8f4e622ee9b8b446163a7061af43"],["/2020/07/04/PicGo-gitee搭建个人免费图床/index.html","2bae9453cc584a65485cc4629917cd3f"],["/2020/07/10/vim日常使用指令/index.html","b2ba6707384f5497dddf60eb08577ddf"],["/2020/07/30/C-笔试-面试题/index.html","43e45889a3d885316e65d5d049846c00"],["/2020/08/08/Ubuntu升级Python3-7后终端无法打开的解决方法/index.html","640d543de434a7d75630b968cd6db7e3"],["/2020/08/21/nginx-fastfds配置完成后worker报错exited-on-signal-11-core-dumped-的解决方法/index.html","8ef2412d7220fc3aa10254b23edf464c"],["/2020/11/22/git版本控制/index.html","4de99f09b367871e2bf97ec67aaf013b"],["/2021/01/31/mysql数据库笔记/index.html","2121f4f9603ed319833b0b8f91c07354"],["/2021/01/31/操作系统笔记/index.html","0efb24a9597920511fcdb38eff57ee0a"],["/2021/01/31/计算机网络笔记/index.html","e55fea79998bfc10814f6cbad28ced02"],["/404.html","5ec0ff1e58b14cfeda3c50c3ad8a2759"],["/Message/index.html","a440b66a8d9bc72f3c1322f078c0ea3a"],["/about/index.html","8fe425a3246cb5284a12cb3c31d880de"],["/archives/2020/07/index.html","709256798d2b24ecb654bb2e5aa646a3"],["/archives/2020/08/index.html","79cc079e2fefd9fca03d5a21967dcd0e"],["/archives/2020/11/index.html","4894035ee52536c81a9b3845e32b5f79"],["/archives/2020/index.html","2232beb2160e041b7e78d302e377d0c7"],["/archives/2021/01/index.html","15c92e03de8756b497091632f3de2bfa"],["/archives/2021/index.html","7568638d9db3601a97cbd025188a77ba"],["/archives/index.html","86fb30568f9ff2ee5759fbf6092db544"],["/archives/page/2/index.html","86fb30568f9ff2ee5759fbf6092db544"],["/baidu_verify_ic5Oqvod58.html","f9b8275e4d938ca419dbbb658663b062"],["/categories/index.html","51d9758a9ba8fbc050c9a7214371faef"],["/categories/后台/index.html","3b5d6f286a0abd3fd49c02783d4fd291"],["/categories/工具/index.html","22a8651e41e45bd9019536c03fa11b70"],["/categories/避坑小记/index.html","f491e4e42f24f49a0d0782ea9e52d256"],["/css/style.css","66c50d9508049cdb89c9d0723287749e"],["/fonts/Monaco.ttf","7d1b5cf51af724a2641a89a881b342fe"],["/fonts/Skranji-Regular.ttf","0f860580e235e4ae4ae655c2bbb9c943"],["/fonts/Ubuntu-Regular.ttf","75adbf87abbf62e27f6a738caeb71f75"],["/friends/index.html","e86fcc2a723f8295e13a47ce89502578"],["/img/algolia.svg","7907ab6b9a7b05076e0751fa3a0bda3a"],["/img/azure.svg","570248db796e292bf7b59a650cd079c8"],["/img/baidu.svg","dc8c2616588c33ff4f70f43579c639d6"],["/index.html","f59f68dbbaa8b2ce21d2f7e7c4cce4ab"],["/js/app.js","ea306851b6276a0ffeec351d138589e5"],["/js/search.js","8c5e55f8a12105822ef6793c880f0aa7"],["/js/valine.js","c60f3b49c9e99acb104d76e10c385c5c"],["/mylist/index.html","106c1f14db7e73f118e54ba72017d762"],["/page/2/index.html","fbbb9b24a8978c5e9f6479a442f8d4ed"],["/tags/C/index.html","7d6269e51ae559ccaa82a6364b3d908d"],["/tags/Gitee/index.html","54431a561ec78b6fb7e4b07b9b855f66"],["/tags/MySQL/index.html","e559338608786e20504fe825b17f522e"],["/tags/PicGo/index.html","4a043db117c4e7baa385f4dd2b1d5396"],["/tags/Ubuntu/index.html","a1c853bc4f9d1c8c5f3bb6db09b0ce51"],["/tags/fastdfs/index.html","7057435414d78f3d355771fa634ae47d"],["/tags/git/index.html","a4c005138b30051b9e96ad542d9d92f1"],["/tags/index.html","41eb90c2849945c644963037c88f3cd5"],["/tags/nginx/index.html","78a3126227b53120556c29a50a8b7310"],["/tags/vim/index.html","c7bb2b64bae837cdb015acc23cfa91c2"],["/tags/图床/index.html","5c7513f23c7c157ae1267d6f30dbaa56"],["/tags/操作系统/index.html","df0b4f47d3af78461e22cced1d22f31a"],["/tags/计算机网络/index.html","52cf57f13396cdacc23cc99dc14ef46b"]];
var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');


var ignoreUrlParametersMatching = [/^utm_/];



var addDirectoryIndex = function(originalUrl, index) {
    var url = new URL(originalUrl);
    if (url.pathname.slice(-1) === '/') {
      url.pathname += index;
    }
    return url.toString();
  };

var cleanResponse = function(originalResponse) {
    // If this is not a redirected response, then we don't have to do anything.
    if (!originalResponse.redirected) {
      return Promise.resolve(originalResponse);
    }

    // Firefox 50 and below doesn't support the Response.body stream, so we may
    // need to read the entire body to memory as a Blob.
    var bodyPromise = 'body' in originalResponse ?
      Promise.resolve(originalResponse.body) :
      originalResponse.blob();

    return bodyPromise.then(function(body) {
      // new Response() is happy when passed either a stream or a Blob.
      return new Response(body, {
        headers: originalResponse.headers,
        status: originalResponse.status,
        statusText: originalResponse.statusText
      });
    });
  };

var createCacheKey = function(originalUrl, paramName, paramValue,
                           dontCacheBustUrlsMatching) {
    // Create a new URL object to avoid modifying originalUrl.
    var url = new URL(originalUrl);

    // If dontCacheBustUrlsMatching is not set, or if we don't have a match,
    // then add in the extra cache-busting URL parameter.
    if (!dontCacheBustUrlsMatching ||
        !(url.pathname.match(dontCacheBustUrlsMatching))) {
      url.search += (url.search ? '&' : '') +
        encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);
    }

    return url.toString();
  };

var isPathWhitelisted = function(whitelist, absoluteUrlString) {
    // If the whitelist is empty, then consider all URLs to be whitelisted.
    if (whitelist.length === 0) {
      return true;
    }

    // Otherwise compare each path regex to the path of the URL passed in.
    var path = (new URL(absoluteUrlString)).pathname;
    return whitelist.some(function(whitelistedPathRegex) {
      return path.match(whitelistedPathRegex);
    });
  };

var stripIgnoredUrlParameters = function(originalUrl,
    ignoreUrlParametersMatching) {
    var url = new URL(originalUrl);
    // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290
    url.hash = '';

    url.search = url.search.slice(1) // Exclude initial '?'
      .split('&') // Split into an array of 'key=value' strings
      .map(function(kv) {
        return kv.split('='); // Split each 'key=value' string into a [key, value] array
      })
      .filter(function(kv) {
        return ignoreUrlParametersMatching.every(function(ignoredRegex) {
          return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.
        });
      })
      .map(function(kv) {
        return kv.join('='); // Join each [key, value] array into a 'key=value' string
      })
      .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each

    return url.toString();
  };


var hashParamName = '_sw-precache';
var urlsToCacheKeys = new Map(
  precacheConfig.map(function(item) {
    var relativeUrl = item[0];
    var hash = item[1];
    var absoluteUrl = new URL(relativeUrl, self.location);
    var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);
    return [absoluteUrl.toString(), cacheKey];
  })
);

function setOfCachedUrls(cache) {
  return cache.keys().then(function(requests) {
    return requests.map(function(request) {
      return request.url;
    });
  }).then(function(urls) {
    return new Set(urls);
  });
}

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return setOfCachedUrls(cache).then(function(cachedUrls) {
        return Promise.all(
          Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {
            // If we don't have a key matching url in the cache already, add it.
            if (!cachedUrls.has(cacheKey)) {
              var request = new Request(cacheKey, {credentials: 'same-origin'});
              return fetch(request).then(function(response) {
                // Bail out of installation unless we get back a 200 OK for
                // every request.
                if (!response.ok) {
                  throw new Error('Request for ' + cacheKey + ' returned a ' +
                    'response with status ' + response.status);
                }

                return cleanResponse(response).then(function(responseToCache) {
                  return cache.put(cacheKey, responseToCache);
                });
              });
            }
          })
        );
      });
    }).then(function() {
      
      // Force the SW to transition from installing -> active state
      return self.skipWaiting();
      
    })
  );
});

self.addEventListener('activate', function(event) {
  var setOfExpectedUrls = new Set(urlsToCacheKeys.values());

  event.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.keys().then(function(existingRequests) {
        return Promise.all(
          existingRequests.map(function(existingRequest) {
            if (!setOfExpectedUrls.has(existingRequest.url)) {
              return cache.delete(existingRequest);
            }
          })
        );
      });
    }).then(function() {
      
      return self.clients.claim();
      
    })
  );
});


self.addEventListener('fetch', function(event) {
  if (event.request.method === 'GET') {
    // Should we call event.respondWith() inside this fetch event handler?
    // This needs to be determined synchronously, which will give other fetch
    // handlers a chance to handle the request if need be.
    var shouldRespond;

    // First, remove all the ignored parameters and hash fragment, and see if we
    // have that URL in our cache. If so, great! shouldRespond will be true.
    var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);
    shouldRespond = urlsToCacheKeys.has(url);

    // If shouldRespond is false, check again, this time with 'index.html'
    // (or whatever the directoryIndex option is set to) at the end.
    var directoryIndex = 'index.html';
    if (!shouldRespond && directoryIndex) {
      url = addDirectoryIndex(url, directoryIndex);
      shouldRespond = urlsToCacheKeys.has(url);
    }

    // If shouldRespond is still false, check to see if this is a navigation
    // request, and if so, whether the URL matches navigateFallbackWhitelist.
    var navigateFallback = '';
    if (!shouldRespond &&
        navigateFallback &&
        (event.request.mode === 'navigate') &&
        isPathWhitelisted([], event.request.url)) {
      url = new URL(navigateFallback, self.location).toString();
      shouldRespond = urlsToCacheKeys.has(url);
    }

    // If shouldRespond was set to true at any point, then call
    // event.respondWith(), using the appropriate cache key.
    if (shouldRespond) {
      event.respondWith(
        caches.open(cacheName).then(function(cache) {
          return cache.match(urlsToCacheKeys.get(url)).then(function(response) {
            if (response) {
              return response;
            }
            throw Error('The cached response that was expected is missing.');
          });
        }).catch(function(e) {
          // Fall back to just fetch()ing the request if some unexpected error
          // prevented the cached response from being valid.
          console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e);
          return fetch(event.request);
        })
      );
    }
  }
});







